home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
140_01
/
zcasm14.c
< prev
Wrap
Text File
|
1985-03-09
|
24KB
|
957 lines
/*
ZCASM.C -- a modification of Leor Zolman's CASM.C
Copyright (c) 1983 Brian Waldron, Xerox Corporation
Altered to accept standard ZILOG Z80 mnemonics and output
short labels for consumption by Microsoft's M80/L80
See the CASM Appendix in the BDSC User's Guide for
complete information.
Compile and link with:
cc zcasm.c -o -e4300
l2 zcasm
(or) clink zcasm
ver. 1.0 7 Oct 83 blw
ver. 1.1 11 Oct 83 blw
changed DB, DW, DS to DEFB, DEFW, DEFS
and modified putdir() accordingly
ver. 1.2 17 Oct 83 blw
cleaned up numerous typos
ver 1.2 released to PD January 1984
ver. 1.3 21 Feb 84 blw
Allowed underscore(_) in function names
ver. 1.4 27 Mar 85 Lindsay Haisley - Austin, TX.
Fixed numerous lethal bugs associated with the
EXTERNAL ZCASM pseudo op. The list of needed
functions (*nflist) will now include the name
of the current function itself, thus avoiding
multiple lables when EXTERNAL functions are
referenced. Several initializers in "for" loops
were changed to accomodate this modification.
Two "JMP" statements changed to "JP" statements
for Z80. One fprintf2 statement fixed so that
the number of arguments agrees with the number
of conversion characters.
ZCASM is hereby placed in the public domain with the restriction
that it may not be distributed for profit.
*/
#include <bdscio.h>
#define TITLE "BDS C CRL-format M80/L80 Preprocessor ver. 1.4\n"
/*
* Customizable definitions:
*/
#define DEFUSER "9/" /* default user area for include files */
/* make this a null string for "current" */
#define DEFDISK "A:" /* default disk for include files */
#define ZCASMEXT ".CZM" /* extension on input files */
#define ASMEXT ".MAC" /* extension on output files */
#define SUBFILE "A:ZZZ.FOO" /* Submit file to erase on error. To not */
/* erase any, use a null string ("") */
#define CONTROL_C 3 /* Abort character */
#define EQUMAX 500 /* maximum number of EQU ops */
#define FUNCMAX 100 /* maximum number of functions */
#define NFMAX 100 /* maximum number of external functions
in one function */
#define LABMAX 150 /* max number of local labels in 1 func */
#define TXTBUFSIZE 2000 /* max # of chars for labels and needed
function names for a single function */
/* the following stuff implements a symbol table for
the purpose of shortening labels to accommidate M80 */
#define MAXSYMS 150 /* max # of entries in label */
/* innumeration table */
#define MAXCHARS 1500 /* max # of chars in lable */
/* innumeration table */
char *str_name[MAXSYMS]; /* array of symbol table entries */
char sym_buff[MAXCHARS]; /* symbol table */
char *next_sym; /* pointer to next empty slot */
int current_syms; /* # of currently defined entries */
/*
* End of customizable section
*/
#define DIRSIZE 512 /* max # of byte in CRL directory */
#define TPALOC 0x100 /* base of TPA in your system */
/* Global data used throughout processing
of the input file: */
char fbuf[BUFSIZ]; /* I/O buffer for main input file */
char incbuf[BUFSIZ]; /* I/O buffer for included file */
char obuf[BUFSIZ]; /* I/O buffer for output file */
char *cbufp; /* ptr to currently active inp buf */
char *cfilnam; /* ptr to name of current inp file */
char nambuf[30], /* filenames for current intput */
nambuf2[30], /* and output files. */
onambuf[30];
char *equtab[EQUMAX]; /* table of absolute symbols */
int equcount; /* # of entries in equtab */
char *fnames[FUNCMAX]; /* list of functions in the file */
int fcount; /* # of entries in fnames */
int lino,savlino; /* line number values used for
error reporting. */
char doingfunc; /* true if now processing a function */
char errf; /* true if an error has been detected */
char verbose; /* true to output wordy comments */
char blankflag; /* true if last line processed was null */
/* Global data used during the processing of a
single function in the source file: */
char *nflist[NFMAX]; /* list of needed functions */
int nfcount; /* number of entries in nflist */
struct {
char *labnam; /* name of function label */
char defined; /* whether it has been defined yet */
} lablist[LABMAX];
int labcount; /* # of local labels in a function */
char txtbuf[TXTBUFSIZE], /* where text of needed function */
*txtbufp; /* names and function labels go */
char linbuf[150], /* text line buffers */
linsav[150],
workbuf[150],
pbuf[150], *pbufp;
char *cfunam; /* pointer to name of current function */
int relblc; /* relocation object count for a function */
char pastnfs; /* true if past all needed functions */
/* declarations ("external" pseudo ops) */
int argcnt; /* values set by "parse_line" function */
char *label,
*op,
*argsp,
*args[40];
char *gpcptr; /* general-purpose text pointer */
char temp_string[20]; /* scratch text buffer */
/*
* Open main input file, open output file, initialize needed globals
* and process the file:
*/
main(aarghc,aarghv)
char **aarghv;
{
int i,j,k;
char c, *inpnam, *outnam;
puts(TITLE);
initequ(); /* init EQU table with reserved words */
fcount = 0; /* haven't seen any functions yet */
doingfunc = FALSE; /* not currently processing a function */
errf = FALSE; /* no errors yet */
verbose = FALSE;
inpnam = outnam = NULL; /* haven't seen any names yet */
blankflag = FALSE; /* haven't just processed a null line */
while (--aarghc)
{
++aarghv; /* bump to next arg text */
if (**aarghv == '-')
{
switch(c = aarghv[0][1])
{
case 'C':
verbose = 1;
break;
case 'O':
if (aarghv[0][2])
outnam = &aarghv[0][2];
else if (--aarghc)
outnam = *++aarghv;
else goto usage;
break;
default: goto usage;
}
}
else
inpnam = *aarghv;
}
if (!inpnam) {
usage: puts("Usage:\tzcasm [-c] [-o <name>] <filename>\n");
puts("-C: don't strip comments from input and output\n");
puts("-O <name>: Call the output file <name>.MAC\n");
if(*SUBFILE) unlink(SUBFILE);
exit();
}
/* set up filenames with proper extensions: */
for (i = 0; (c = inpnam[i]) && c != '.'; i++)
nambuf[i] = c;
nambuf[i] = '\0';
strcpy(onambuf, outnam ? outnam : nambuf);
strcat(nambuf,ZCASMEXT); /* input filename */
cbufp = fbuf; /* buffer pointer */
cfilnam = nambuf; /* current filename pointer */
if (fopen(cfilnam,cbufp) == ERROR){
if (*SUBFILE) unlink(SUBFILE);
exit(printf("Can't open %s\n",cfilnam));
}
if (!hasdot(onambuf))
strcat(onambuf,ASMEXT); /* output filename */
if (fcreat(onambuf,obuf) == ERROR){
if(*SUBFILE) unlink(SUBFILE);
exit(printf("Can't create %s\n",onambuf));
}
/* begin writing output file */
fprintf2(obuf,"\nTPALOC\tEQU\t%04xH\n",TPALOC);
lino = 1; /* initialize line count */
while (get_line()) { /* main loop */
if (kbhit() && getchar() == CONTROL_C)
abort("Aborted by ^C\n");
process_line(); /* process lines till EOF */
lino++;
}
if (doingfunc) /* if ends inside a function, error */
abort("File ends, but last function is unterminated\n");
if (errf)
{
puts("Fix those errors and try again...");
unlink(onambuf);
if (*SUBFILE)
unlink(SUBFILE);
}
else
{
/* end of functions */
fputs2("\nEND$CRL\tEQU\t$-TPALOC\n",obuf);
putdir(); /* now put out CRL dir. */
fputs2("\tEND\n",obuf); /* end of ASM file */
putc(CPMEOF,obuf); /* CP/M EOF char. */
fclose(cbufp); /* close input file */
fclose(obuf); /* close output file */
printf("%s is ready to be assembled.\n",onambuf);
}
}
/*
* Get a line of text from input stream, and process
* "include" ops on the fly:
*/
int get_line()
{
int i;
top: if (!fgets(linbuf,cbufp)) { /* on EOF: */
if (cbufp == incbuf) { /* in an "include" file?*/
fabort(cbufp->_fd); /* close the file */
cbufp = fbuf; /* go back t